<template>
  <div class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-br from-purple-200 to-blue-100 p-2">

    <div class="flex flex-col sm:flex-row items-center justify-center gap-4 mb-6">
      <h1 class="text-3xl font-bold text-purple-700">页面未发现</h1>
      <button
        class="mt-2 sm:mt-0 sm:ml-6 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors shadow-md hover:shadow-lg focus:outline-none focus:ring-4 focus:ring-blue-300 active:scale-95"
        @click="$router.push('/')">
        返回主页
      </button>
    </div>

    <!-- <h1 class="text-3xl font-bold mb-4 text-purple-700">2048小游戏</h1> -->
    <div class="bg-white rounded-xl shadow-lg p-4 flex flex-col items-center w-full max-w-xs sm:max-w-md">
      <div class="flex justify-between w-full mb-2">
        <span class="font-bold text-lg text-purple-600">分数: {{ score }}</span>
        <button class="bg-purple-500 text-white px-3 py-1 rounded hover:bg-purple-600 transition"
          @click="resetGame">重置</button>
      </div>
      <div class="grid gap-2" :class="[
        'grid-cols-4',
        'grid-rows-4',
        'w-72',
        'h-72',
        'sm:w-96',
        'sm:h-96'
      ]" @touchstart="handleTouchStart" @touchend="handleTouchEnd" tabindex="0" @keydown="handleKey">
        <div v-for="(cell, idx) in flatGrid" :key="idx"
          class="flex items-center justify-center rounded text-xl font-bold transition-all duration-200" :class="[
            'bg-gray-100',
            cell ? tileColors[cell] || 'bg-yellow-200 text-gray-800' : 'bg-gray-200',
            cell ? 'shadow' : '',
            'select-none'
          ]">
          {{ cell || '' }}
        </div>
      </div>
      <div v-if="gameOver" class="mt-4 text-red-500 font-bold">游戏结束！</div>
      <div v-if="win" class="mt-4 text-green-600 font-bold">你赢了！</div>
      <div class="mt-2 text-xs text-gray-400">方向键、滑动或下方按键操作</div>
      <!-- 四个方向按键 -->
      <div class="mt-4 flex flex-col items-center gap-2 select-none">
        <button
          class="w-12 h-12 rounded-full bg-purple-400 text-white text-2xl flex items-center justify-center shadow hover:bg-purple-500 active:bg-purple-600 transition"
          @click="move('up')" aria-label="上">↑</button>
        <div class="flex gap-8">
          <button
            class="w-12 h-12 rounded-full bg-purple-400 text-white text-2xl flex items-center justify-center shadow hover:bg-purple-500 active:bg-purple-600 transition"
            @click="move('left')" aria-label="左">←</button>
          <button
            class="w-12 h-12 rounded-full bg-purple-400 text-white text-2xl flex items-center justify-center shadow hover:bg-purple-500 active:bg-purple-600 transition"
            @click="move('right')" aria-label="右">→</button>
        </div>
        <button
          class="w-12 h-12 rounded-full bg-purple-400 text-white text-2xl flex items-center justify-center shadow hover:bg-purple-500 active:bg-purple-600 transition"
          @click="move('down')" aria-label="下">↓</button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'

const size = 4
const grid = ref<number[][]>([])
const score = ref(0)
const gameOver = ref(false)
const win = ref(false)

const tileColors: Record<number, string> = {
  2: 'bg-yellow-50 text-gray-700',
  4: 'bg-yellow-100 text-gray-700',
  8: 'bg-yellow-200 text-orange-700',
  16: 'bg-orange-200 text-orange-800',
  32: 'bg-orange-300 text-orange-900',
  64: 'bg-orange-400 text-white',
  128: 'bg-orange-500 text-white',
  256: 'bg-orange-600 text-white',
  512: 'bg-orange-700 text-white',
  1024: 'bg-purple-400 text-white',
  2048: 'bg-purple-600 text-white',
}

function initGrid() {
  grid.value = Array.from({ length: size }, () => Array(size).fill(0))
  addRandomTile()
  addRandomTile()
  score.value = 0
  gameOver.value = false
  win.value = false
}

function addRandomTile() {
  const empty: [number, number][] = []
  for (let i = 0; i < size; i++) {
    for (let j = 0; j < size; j++) {
      if (grid.value[i][j] === 0) empty.push([i, j])
    }
  }
  if (empty.length === 0) return
  const [i, j] = empty[Math.floor(Math.random() * empty.length)]
  grid.value[i][j] = Math.random() < 0.9 ? 2 : 4
}

function move(dir: 'left' | 'right' | 'up' | 'down') {
  if (gameOver.value || win.value) return
  let mergedScore = 0

  function slide(row: number[]) {
    let arr = row.filter(n => n)
    for (let i = 0; i < arr.length - 1; i++) {
      if (arr[i] && arr[i] === arr[i + 1]) {
        arr[i] *= 2
        mergedScore += arr[i]
        arr[i + 1] = 0
        if (arr[i] === 2048) win.value = true
      }
    }
    arr = arr.filter(n => n)
    while (arr.length < size) arr.push(0)
    return arr
  }

  let old = JSON.stringify(grid.value)
  if (dir === 'left') {
    for (let i = 0; i < size; i++) {
      grid.value[i] = slide(grid.value[i])
    }
  } else if (dir === 'right') {
    for (let i = 0; i < size; i++) {
      grid.value[i] = slide(grid.value[i].slice().reverse()).reverse()
    }
  } else if (dir === 'up') {
    for (let j = 0; j < size; j++) {
      let col = grid.value.map(row => row[j])
      col = slide(col)
      for (let i = 0; i < size; i++) grid.value[i][j] = col[i]
    }
  } else if (dir === 'down') {
    for (let j = 0; j < size; j++) {
      let col = grid.value.map(row => row[j]).reverse()
      col = slide(col)
      col = col.reverse()
      for (let i = 0; i < size; i++) grid.value[i][j] = col[i]
    }
  }
  if (JSON.stringify(grid.value) !== old) {
    addRandomTile()
    score.value += mergedScore
  }
  checkGameOver()
}

function checkGameOver() {
  for (let i = 0; i < size; i++) {
    for (let j = 0; j < size; j++) {
      if (grid.value[i][j] === 0) return (gameOver.value = false)
      if (i < size - 1 && grid.value[i][j] === grid.value[i + 1][j]) return (gameOver.value = false)
      if (j < size - 1 && grid.value[i][j] === grid.value[i][j + 1]) return (gameOver.value = false)
    }
  }
  gameOver.value = true
}

function resetGame() {
  initGrid()
}

const flatGrid = computed(() => grid.value.flat())

// 键盘操作
function handleKey(e: KeyboardEvent) {
  if (e.key === 'ArrowLeft') move('left')
  if (e.key === 'ArrowRight') move('right')
  if (e.key === 'ArrowUp') move('up')
  if (e.key === 'ArrowDown') move('down')
}

// 触摸操作
let startX = 0, startY = 0
function handleTouchStart(e: TouchEvent) {
  const t = e.touches[0]
  startX = t.clientX
  startY = t.clientY
}
function handleTouchEnd(e: TouchEvent) {
  const t = e.changedTouches[0]
  const dx = t.clientX - startX
  const dy = t.clientY - startY
  if (Math.abs(dx) > Math.abs(dy)) {
    if (dx > 30) move('right')
    else if (dx < -30) move('left')
  } else {
    if (dy > 30) move('down')
    else if (dy < -30) move('up')
  }
}

onMounted(() => {
  initGrid()
  window.addEventListener('keydown', handleKey)
})
</script>